home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src-tk / tkwndws.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-24  |  28.3 KB  |  1,099 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37.  
  38. // Mesa Tweaking by: Mark E. Peterson (markp@ic.mankato.mn.us)
  39.  
  40. #include <windows.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include "gltk.h"
  45. #include "gl\wmesa.h"
  46.  
  47. #define static
  48.  
  49. #if defined(__cplusplus) || defined(c_plusplus)
  50. #define class c_class
  51. #endif
  52.  
  53. #if DBG
  54. #define TKASSERT(x)                                     \
  55. if ( !(x) ) {                                           \
  56.     PrintMessage("%s(%d) Assertion failed %s\n",        \
  57.         __FILE__, __LINE__, #x);                        \
  58. }
  59. #else
  60. #define TKASSERT(x)
  61. #endif  /* DBG */
  62.  
  63. /******************************************************************************/
  64.  
  65. static struct _WINDOWINFO {
  66.     int x, y;
  67.     int width, height;
  68.     GLenum type;
  69.     GLenum dmPolicy;
  70.     int ipfd;
  71.     BOOL bDefPos;
  72. } windInfo = {
  73.     0, 0, 100, 100, TK_INDEX | TK_SINGLE, TK_MINIMUM_CRITERIA, 0, TRUE
  74. };
  75.  
  76.  
  77. static HWND     tkhwnd     = NULL;
  78. static HDC      tkhdc      = NULL;
  79. static HPALETTE tkhpalette = NULL;
  80. GLboolean tkPopupEnable = TRUE;
  81.  
  82. // Fixed palette support.
  83.  
  84. #define BLACK   PALETTERGB(0,0,0)
  85. #define WHITE   PALETTERGB(255,255,255)
  86. #define NUM_STATIC_COLORS   (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
  87.  
  88. static void (*ExposeFunc)(int, int)              = NULL;
  89. static void (*ReshapeFunc)(GLsizei, GLsizei)     = NULL;
  90. static void (*DisplayFunc)(void)                 = NULL;
  91. static GLenum (*KeyDownFunc)(int, GLenum)        = NULL;
  92. static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
  93. static GLenum (*MouseUpFunc)(int, int, GLenum)   = NULL;
  94. static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
  95. static void (*IdleFunc)(void)                    = NULL;
  96.  
  97. static char     *lpszClassName = "tkLibWClass";
  98. static WCHAR    *lpszClassNameW = L"tkLibWClass";
  99.  
  100. long FAR PASCAL _export tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
  101. static unsigned char ComponentFromIndex(int i, int nbits, int shift );
  102. static void PrintMessage( const char *Format, ... );
  103. //static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );
  104. static HPALETTE CreateCIPalette( HDC Dc );
  105. static HPALETTE CreateRGBPalette( HDC hdc );
  106. static void DestroyThisWindow( HWND Window );
  107. static void CleanUp( void );
  108. static void DelayPaletteRealization( void );
  109. static long RealizePaletteNow( HDC Dc, HPALETTE Palette);
  110. static void ForceRedraw( HWND Window );
  111. static void *AllocateMemory( size_t Size );
  112. static void *AllocateZeroedMemory( size_t Size );
  113. static void FreeMemory( void *Chunk );
  114.  
  115. /*
  116.  *  Prototypes for the debugging functions go here
  117.  */
  118.  
  119. #define DBGFUNC 0
  120. #if DBGFUNC
  121.  
  122. static void DbgPrintf( const char *Format, ... );
  123. static void pwi( void );
  124. static void pwr(RECT *pr);
  125. //static void ShowPixelFormat(HDC hdc);
  126.  
  127. #endif
  128. #define NCOLORS 17
  129. float tkRGBMap[NCOLORS][3] = {
  130.     {0,0,0},
  131.     {0,0,0},
  132.     {0,0,0},
  133.     {0,0,0},
  134.     {0,0,0},
  135.     {0,0,0},
  136.     {0,0,0},
  137.     {0,0,0},
  138.     {0,0,0},
  139.     {0,0,0},
  140.     {1,0,0},
  141.     {0,1,0},
  142.     {1,1,0},
  143.     {0,0,1},
  144.     {1,0,1},
  145.     {0,1,1},
  146.     {1,1,1}
  147. };
  148.  
  149.  
  150. /***************************************************************
  151.  *                                                             *
  152.  *  Exported Functions go here                                 *
  153.  *                                                             *
  154.  ***************************************************************/
  155.  
  156. void tkErrorPopups(GLboolean bEnable)
  157. {
  158.     tkPopupEnable = bEnable;
  159. }
  160.  
  161. void tkCloseWindow(void)
  162. {
  163.     DestroyThisWindow(tkhwnd);
  164.     /* if (w.cMain) {
  165.        XMesaDestroyContext(w.cMain);
  166.     }*/
  167.     WMesaDestroyContext(NULL);
  168. }
  169.  
  170.  
  171. void tkExec(void)
  172. {
  173.     MSG Message;
  174.  
  175.     /*
  176.      *  WM_SIZE gets delivered before we get here!
  177.      */
  178.  
  179.     if (ReshapeFunc)
  180.     {
  181.         RECT ClientRect;
  182.  
  183.         GetClientRect(tkhwnd, &ClientRect);
  184.         (*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
  185.     }
  186.  
  187.     while (GL_TRUE)
  188.     {
  189.         /*
  190.          *  Process all pending messages
  191.          */
  192.  
  193.         while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE)
  194.         {
  195.             if (GetMessage(&Message, NULL, 0, 0) )
  196.             {
  197.                 TranslateMessage(&Message);
  198.                 DispatchMessage(&Message);
  199.             }
  200.             else
  201.             {
  202.                 /*
  203.                  *  Nothing else to do here, just return
  204.                  */
  205.  
  206.                 return;
  207.             }
  208.         }
  209.  
  210.         /*
  211.          *  If an idle function was defined, call it
  212.          */
  213.  
  214.         if (IdleFunc)
  215.         {
  216.             (*IdleFunc)();
  217. /* Code added by Li Wei    (liwei@aiar.xjtu.edu.cn)*/
  218.             ForceRedraw(tkhwnd);
  219. /* End modification by Li Wei    */
  220.         }
  221.     }
  222. }
  223.  
  224. void tkExposeFunc(void (*Func)(int, int))
  225. {
  226.     ExposeFunc = Func;
  227. }
  228.  
  229. void tkReshapeFunc(void (*Func)(GLsizei, GLsizei))
  230. {
  231.     ReshapeFunc = Func;
  232. }
  233.  
  234. void tkDisplayFunc(void (*Func)(void))
  235. {
  236.     DisplayFunc = Func;
  237. }
  238.  
  239. void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
  240. {
  241.     KeyDownFunc = Func;
  242. }
  243.  
  244. void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
  245. {
  246.     MouseDownFunc = Func;
  247. }
  248.  
  249. void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
  250. {
  251.     MouseUpFunc = Func;
  252. }
  253.  
  254. void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
  255. {
  256.     MouseMoveFunc = Func;
  257. }
  258.  
  259. void tkIdleFunc(void (*Func)(void))
  260. {
  261.     IdleFunc = Func;
  262. }
  263.  
  264. void tkInitPosition(int x, int y, int width, int height)
  265. {
  266.     if (x == CW_USEDEFAULT)
  267.     {
  268.         x = 0;
  269.         y = 0;
  270.         windInfo.bDefPos = TRUE;
  271.     }
  272.     else
  273.         windInfo.bDefPos = FALSE;
  274.  
  275.     windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
  276.     windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
  277.                  - GetSystemMetrics(SM_CYBORDER)
  278.                  + GetSystemMetrics(SM_CYFRAME);
  279.     windInfo.width = width;
  280.     windInfo.height = height;
  281. }
  282.  
  283. void tkInitDisplayMode(GLenum type)
  284. {
  285.     windInfo.type = type;
  286. }
  287.  
  288. void tkInitDisplayModePolicy(GLenum type)
  289. {
  290.     windInfo.dmPolicy = type;
  291. }
  292.  
  293. GLenum tkInitDisplayModeID(GLint ipfd)
  294. {
  295.     windInfo.ipfd = ipfd;
  296.     return GL_TRUE;
  297. }
  298.  
  299. GLenum tkInitWindowAW(char *title, BOOL bUnicode)
  300. {
  301.     WMesaContext Cur;
  302.     WNDCLASS wndclass;
  303.     RECT     WinRect;
  304.     HANDLE   hInstance;
  305.     ATOM     aRegister;
  306.     GLenum   Result = GL_FALSE,RGB_Flag=GL_TRUE,DB_Flag=GL_FALSE;
  307.  
  308.     hInstance = GetModuleHandle(NULL);
  309.  
  310.     // Must not define CS_CS_PARENTDC style.
  311.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  312.     wndclass.lpfnWndProc   = (WNDPROC)tkWndProc;
  313.     wndclass.cbClsExtra    = 0;
  314.     wndclass.cbWndExtra    = 0;
  315.     wndclass.hInstance     = hInstance;
  316.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  317.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  318.     wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
  319.     wndclass.lpszMenuName  = NULL;
  320.  
  321.     if (bUnicode)
  322.         wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
  323.     else
  324.         wndclass.lpszClassName = (LPCSTR)lpszClassName;
  325.  
  326.     if (bUnicode)
  327.     {
  328.         aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
  329.     }
  330.     else
  331.     {
  332.         aRegister = RegisterClass(&wndclass);
  333.     }
  334.  
  335.  
  336.     /*
  337.      *  If the window failed to register, then there's no
  338.      *  need to continue further.
  339.      */
  340.  
  341.     if(0 == aRegister)
  342.     {
  343.         PrintMessage("Failed to register window class\n");
  344.         return(Result);
  345.     }
  346.  
  347.  
  348.     /*
  349.      *  Make window large enough to hold a client area as large as windInfo
  350.      */
  351.  
  352.     WinRect.left   = windInfo.x;
  353.     WinRect.right  = windInfo.x + windInfo.width;
  354.     WinRect.top    = windInfo.y;
  355.     WinRect.bottom = windInfo.y + windInfo.height;
  356.  
  357.     AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  358.  
  359.     /*
  360.      *  Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
  361.      */
  362.  
  363.     if (bUnicode)
  364.     {
  365.         tkhwnd = CreateWindowW(
  366.                     (LPCWSTR)lpszClassNameW,
  367.                     (LPCWSTR)title,
  368.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  369.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  370.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  371.                     WinRect.right - WinRect.left,
  372.                     WinRect.bottom - WinRect.top,
  373.                     NULL,
  374.                     NULL,
  375.                     hInstance,
  376.                     NULL);
  377.     }
  378.     else
  379.     {
  380.         tkhwnd = CreateWindow(
  381.                     lpszClassName,
  382.                     title,
  383.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  384.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  385.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  386.                     WinRect.right - WinRect.left,
  387.                     WinRect.bottom - WinRect.top,
  388.                     NULL,
  389.                     NULL,
  390.                     hInstance,
  391.                     NULL);
  392.     }
  393.  
  394.     if ( NULL != tkhwnd )
  395.     {
  396.         // If default window positioning used, find out window position and fix
  397.         // up the windInfo position info.
  398.  
  399.         if (windInfo.bDefPos)
  400.         {
  401.             GetWindowRect(tkhwnd, &WinRect);
  402.             windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
  403.             windInfo.y = WinRect.top  + GetSystemMetrics(SM_CYCAPTION)
  404.                          - GetSystemMetrics(SM_CYBORDER)
  405.                          + GetSystemMetrics(SM_CYFRAME);
  406.         }
  407.  
  408.         tkhdc = GetDC(tkhwnd);
  409.  
  410.         if ( NULL != tkhdc )
  411.             ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  412.         else
  413.             PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
  414.     }
  415.     else
  416.         PrintMessage("create window failed\n");
  417.     if (windInfo.type & TK_INDEX)
  418.     {
  419.       RGB_Flag=GL_FALSE;
  420.       tkSetRGBMap(NCOLORS,(float *) tkRGBMap);
  421.     }
  422.     if (windInfo.type & TK_DOUBLE)
  423.       DB_Flag=GL_TRUE;
  424.     Cur=WMesaCreateContext(tkhwnd,tkhpalette,RGB_Flag,DB_Flag);
  425.     WMesaMakeCurrent(Cur);
  426.     return GL_TRUE;
  427. }
  428.  
  429. // Initialize a window, create a rendering context for that window
  430. GLenum tkInitWindow(char *title)
  431. {
  432.     TKASSERT( NULL==tkhwnd      );
  433.     TKASSERT( NULL==tkhdc       );
  434.     TKASSERT( NULL==tkhrc       );
  435.     TKASSERT( NULL==tkhpalette  );
  436.  
  437.     return tkInitWindowAW(title, FALSE);
  438. }
  439.  
  440.  
  441. /******************************************************************************/
  442.  
  443. /*
  444.  * You cannot just call DestroyWindow() here.  The programs do not expect
  445.  * tkQuit() to return;  DestroyWindow() just sends a WM_DESTROY message
  446.  */
  447.  
  448. void tkQuit(void)
  449. {
  450.     DestroyThisWindow(tkhwnd);
  451.     ExitProcess(0);
  452. }
  453.  
  454. /******************************************************************************/
  455.  
  456. void tkSetOneColor(int index, float r, float g, float b)
  457. {
  458.     PALETTEENTRY PalEntry;
  459.     HPALETTE Palette;
  460.     if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
  461.     {
  462.         PalEntry.peRed   = (BYTE)(r*(float)255.0 + (float)0.5);
  463.         PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
  464.         PalEntry.peBlue  = (BYTE)(b*(float)255.0 + (float)0.5);
  465.         PalEntry.peFlags = 0;
  466.         SetPaletteEntries( Palette, index, 1, &PalEntry);
  467.         DelayPaletteRealization();
  468.     }
  469. }
  470.  
  471. void tkSetFogRamp(int density, int startIndex)
  472. {
  473.     HPALETTE CurrentPal;
  474.     PALETTEENTRY *pPalEntry;
  475.     UINT n, i, j, k, intensity, fogValues, colorValues;
  476.  
  477.     if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
  478.     {
  479.         n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  480.  
  481.         pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
  482.  
  483.         if ( NULL != pPalEntry)
  484.         {
  485.             fogValues = 1 << density;
  486.             colorValues = 1 << startIndex;
  487.             for (i = 0; i < colorValues; i++) {
  488.                 for (j = 0; j < fogValues; j++) {
  489.                     k = i * fogValues + j;
  490.  
  491.                     intensity = i * fogValues + j * colorValues;
  492.                     //mf: not sure what they're trying to do here
  493.                     //intensity = (intensity << 8) | intensity; ???
  494.  
  495.                 // This is a workaround for a GDI palette "feature".  If any of
  496.                 // the static colors are repeated in the palette, those colors
  497.                 // will map to the first occurance.  So, for our case where there
  498.                 // are only two static colors (black and white), if a white
  499.                 // color appears anywhere in the palette other than in the last
  500.                 // entry, the static white will remap to the first white.  This
  501.                 // destroys the nice one-to-one mapping we are trying to achieve.
  502.                 //
  503.                 // There are two ways to workaround this.  The first is to
  504.                 // simply not allow a pure white anywhere but in the last entry.
  505.                 // Such requests are replaced with an attenuated white of
  506.                 // (0xFE, 0xFE, 0xFE).
  507.                 //
  508.                 // The other way is to mark these extra whites with PC_RESERVED
  509.                 // which will cause GDI to skip these entries when mapping colors.
  510.                 // This way the app gets the actual colors requested, but can
  511.                 // have side effects on other apps.
  512.                 //
  513.                 // Both solutions are included below.  The PC_RESERVED solution is
  514.                 // the one currently enabled.  It may have side effects, but taking
  515.                 // over the static colors as we are is a really big side effect that
  516.                 // should swamp out the effects of using PC_RESERVED.
  517.                 if (intensity > 0xFF)
  518.                   intensity = 0xFF;
  519.                 pPalEntry[k].peRed =pPalEntry[k].peGreen = pPalEntry[k].peBlue = (BYTE) intensity;
  520.                 pPalEntry[k].peFlags = 0;
  521.  
  522.                 }
  523.             }
  524.  
  525.             SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
  526.             FreeMemory( pPalEntry );
  527.  
  528.             DelayPaletteRealization();
  529.         }
  530.     }
  531. }
  532.  
  533. void tkSetGreyRamp(void)
  534. {
  535.     HPALETTE CurrentPal;
  536.     PALETTEENTRY *Entries;
  537.     UINT Count, i;
  538.     float intensity;
  539.  
  540.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  541.     {
  542.         Count   = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  543.         Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  544.  
  545.         if ( NULL != Entries )
  546.         {
  547.             for (i = 0; i < Count; i++)
  548.             {
  549.                 intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
  550.                 Entries[i].peRed =
  551.                 Entries[i].peGreen =
  552.                 Entries[i].peBlue = (BYTE) intensity;
  553.                 Entries[i].peFlags = 0;
  554.             }
  555.             SetPaletteEntries( CurrentPal, 0, Count, Entries );
  556.             FreeMemory( Entries );
  557.  
  558.             DelayPaletteRealization();
  559.         }
  560.     }
  561. }
  562.  
  563. void tkSetRGBMap( int Size, float *Values )
  564. {
  565.     HPALETTE CurrentPal;
  566.     int i;
  567.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  568.     {
  569.       for (i=0; i<Size; i++)
  570.         tkSetOneColor(i,Values[i*3],Values[i*3+1],Values[i*3+2]);
  571.     }
  572. }
  573.  
  574. /******************************************************************************/
  575.  
  576. void tkSwapBuffers(void)
  577. {
  578.   WMesaSwapBuffers();
  579. }
  580.  
  581. /******************************************************************************/
  582.  
  583. GLint tkGetColorMapSize(void)
  584. {
  585.     CreateCIPalette( tkhdc );
  586.  
  587.     if ( NULL == tkhpalette )
  588.         return( 0 );
  589.  
  590.     return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
  591. }
  592.  
  593. void tkGetMouseLoc(int *x, int *y)
  594. {
  595.     POINT Point;
  596.  
  597.     *x = 0;
  598.     *y = 0;
  599.  
  600.     GetCursorPos(&Point);
  601.  
  602.     /*
  603.      *  GetCursorPos returns screen coordinates,
  604.      *  we want window coordinates
  605.      */
  606.  
  607.     *x = Point.x - windInfo.x;
  608.     *y = Point.y - windInfo.y;
  609. }
  610.  
  611. HWND tkGetHWND(void)
  612. {
  613.     return tkhwnd;
  614. }
  615.  
  616. HDC tkGetHDC(void)
  617. {
  618.     return tkhdc;
  619. }
  620. GLenum tkGetDisplayModePolicy(void)
  621. {
  622.     return windInfo.dmPolicy;
  623. }
  624.  
  625. GLint tkGetDisplayModeID(void)
  626. {
  627.     return windInfo.ipfd;
  628. }
  629.  
  630. GLenum tkGetDisplayMode(void)
  631. {
  632.     return windInfo.type;
  633. }
  634.  
  635.  
  636. /***********************************************************************
  637.  *                                                                     *
  638.  *  The Following functions are for our own use only. (ie static)      *
  639.  *                                                                     *
  640.  ***********************************************************************/
  641.  
  642. long FAR PASCAL _export
  643. tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
  644. {
  645.     int key;
  646.     PAINTSTRUCT paint;
  647.     HDC hdc;
  648.  
  649.     switch (message)
  650.     {
  651.  
  652.     case WM_USER:
  653.  
  654.         if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  655.             ForceRedraw( hWnd );
  656.         return(0);
  657.  
  658.     case WM_SIZE:
  659.         windInfo.width  = LOWORD(lParam);
  660.         windInfo.height = HIWORD(lParam);
  661.  
  662.         if (ReshapeFunc)
  663.         {
  664.             (*ReshapeFunc)(windInfo.width, windInfo.height);
  665.  
  666.             ForceRedraw( hWnd );
  667.         }
  668.         return (0);
  669.  
  670.     case WM_MOVE:
  671.         windInfo.x = LOWORD(lParam);
  672.         windInfo.y = HIWORD(lParam);
  673.         return (0);
  674.  
  675.     case WM_PAINT:
  676.  
  677.         /*
  678.          *  Validate the region even if there are no DisplayFunc.
  679.          *  Otherwise, USER will not stop sending WM_PAINT messages.
  680.          */
  681.  
  682.         hdc = BeginPaint(tkhwnd, &paint);
  683.  
  684.         if (DisplayFunc)
  685.         {
  686.             (*DisplayFunc)();
  687.         }
  688.  
  689.         EndPaint(tkhwnd, &paint);
  690.         return (0);
  691.  
  692.     case WM_PALETTECHANGED:
  693.         if ( hWnd != (HWND) wParam )
  694.           RealizePaletteNow(tkhdc,tkhpalette);
  695.         return (0);
  696.     case WM_QUERYNEWPALETTE:
  697.  
  698.     // In the foreground!  Let RealizePaletteNow do the work--
  699.     // if management of the static system color usage is needed,
  700.     // RealizePaletteNow will take care of it.
  701.  
  702.         if ( NULL != tkhpalette )
  703.         {
  704.             if ( RealizePaletteNow(tkhdc, tkhpalette) > 0 )
  705.                 ForceRedraw( hWnd );
  706.  
  707.             return (1);
  708.         }
  709.  
  710.         return (0);
  711.  
  712.     case WM_ACTIVATE:
  713.  
  714.     // If the window is going inactive, the palette must be realized to
  715.     // the background.  Cannot depend on WM_PALETTECHANGED to be sent since
  716.     // the window that comes to the foreground may or may not be palette
  717.     // managed.
  718.  
  719.         if ( LOWORD(wParam) == WA_INACTIVE )
  720.         {
  721.             if ( NULL != tkhpalette )
  722.             {
  723.             // Realize as a background palette.  Need to call
  724.             // RealizePaletteNow rather than RealizePalette directly to
  725.             // because it may be necessary to release usage of the static
  726.             // system colors.
  727.  
  728.                 if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  729.                     ForceRedraw( hWnd );
  730.             }
  731.         }
  732.  
  733.     // Allow DefWindowProc() to finish the default processing (which includes
  734.     // changing the keyboard focus).
  735.  
  736.         break;
  737.  
  738.     case WM_MOUSEMOVE:
  739.  
  740.         if (MouseMoveFunc)
  741.         {
  742.             GLenum mask;
  743.  
  744.             mask = 0;
  745.             if (wParam & MK_LBUTTON) {
  746.                 mask |= TK_LEFTBUTTON;
  747.             }
  748.             if (wParam & MK_MBUTTON) {
  749.                 mask |= TK_MIDDLEBUTTON;
  750.             }
  751.             if (wParam & MK_RBUTTON) {
  752.                 mask |= TK_RIGHTBUTTON;
  753.             }
  754.  
  755.             if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  756.             {
  757.                 ForceRedraw( hWnd );
  758.             }
  759.         }
  760.         return (0);
  761.  
  762.     case WM_LBUTTONDOWN:
  763.  
  764.         SetCapture(hWnd);
  765.  
  766.         if (MouseDownFunc)
  767.         {
  768.             if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  769.                  TK_LEFTBUTTON) )
  770.             {
  771.                 ForceRedraw( hWnd );
  772.             }
  773.         }
  774.         return (0);
  775.  
  776.     case WM_LBUTTONUP:
  777.  
  778.         ReleaseCapture();
  779.  
  780.         if (MouseUpFunc)
  781.         {
  782.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  783.             {
  784.                 ForceRedraw( hWnd );
  785.             }
  786.         }
  787.         return (0);
  788.  
  789.     case WM_MBUTTONDOWN:
  790.  
  791.         SetCapture(hWnd);
  792.  
  793.         if (MouseDownFunc)
  794.         {
  795.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  796.                     TK_MIDDLEBUTTON))
  797.             {
  798.                 ForceRedraw( hWnd );
  799.             }
  800.         }
  801.         return (0);
  802.  
  803.     case WM_MBUTTONUP:
  804.  
  805.         ReleaseCapture();
  806.  
  807.         if (MouseUpFunc)
  808.         {
  809.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  810.                 TK_MIDDLEBUTTON))
  811.             {
  812.                 ForceRedraw( hWnd );
  813.             }
  814.         }
  815.         return (0);
  816.  
  817.     case WM_RBUTTONDOWN:
  818.  
  819.         SetCapture(hWnd);
  820.  
  821.         if (MouseDownFunc)
  822.         {
  823.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  824.                 TK_RIGHTBUTTON))
  825.             {
  826.                 ForceRedraw( hWnd );
  827.             }
  828.         }
  829.         return (0);
  830.  
  831.     case WM_RBUTTONUP:
  832.  
  833.         ReleaseCapture();
  834.  
  835.         if (MouseUpFunc)
  836.         {
  837.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  838.                 TK_RIGHTBUTTON))
  839.             {
  840.                 ForceRedraw( hWnd );
  841.             }
  842.         }
  843.         return (0);
  844.  
  845.     case WM_KEYDOWN:
  846.         switch (wParam) {
  847.         case VK_SPACE:          key = TK_SPACE;         break;
  848.         case VK_RETURN:         key = TK_RETURN;        break;
  849.         case VK_ESCAPE:         key = TK_ESCAPE;        break;
  850.         case VK_LEFT:           key = TK_LEFT;          break;
  851.         case VK_UP:             key = TK_UP;            break;
  852.         case VK_RIGHT:          key = TK_RIGHT;         break;
  853.         case VK_DOWN:           key = TK_DOWN;          break;
  854.         default:                key = GL_FALSE;         break;
  855.         }
  856.  
  857.         if (key && KeyDownFunc)
  858.         {
  859.             GLenum mask;
  860.  
  861.             mask = 0;
  862.             if (GetKeyState(VK_CONTROL)) {
  863.                 mask |= TK_CONTROL;
  864.             }
  865.  
  866.             if (GetKeyState(VK_SHIFT)) {
  867.  
  868.                 mask |= TK_SHIFT;
  869.             }
  870.  
  871.             if ( (*KeyDownFunc)(key, mask) )
  872.             {
  873.                 ForceRedraw( hWnd );
  874.             }
  875.         }
  876.         return (0);
  877.  
  878.     case WM_CHAR:
  879.         if (('0' <= wParam && wParam <= '9') ||
  880.             ('a' <= wParam && wParam <= 'z') ||
  881.             ('A' <= wParam && wParam <= 'Z')) {
  882.  
  883.             key = wParam;
  884.         } else {
  885.             key = GL_FALSE;
  886.         }
  887.  
  888.         if (key && KeyDownFunc) {
  889.             GLenum mask;
  890.  
  891.             mask = 0;
  892.  
  893.             if (GetKeyState(VK_CONTROL)) {
  894.                 mask |= TK_CONTROL;
  895.             }
  896.  
  897.             if (GetKeyState(VK_SHIFT)) {
  898.                 mask |= TK_SHIFT;
  899.             }
  900.  
  901.             if ( (*KeyDownFunc)(key, mask) )
  902.             {
  903.                 ForceRedraw( hWnd );
  904.             }
  905.         }
  906.         return (0);
  907.  
  908.     case WM_CLOSE:
  909.         DestroyWindow(tkhwnd);
  910.         return(0);
  911.  
  912.     case WM_DESTROY:
  913.         CleanUp();
  914.         PostQuitMessage(TRUE);
  915.         return 0;
  916.     }
  917.     return(DefWindowProc( hWnd, message, wParam, lParam));
  918. }
  919. static HPALETTE CreateCIPalette( HDC Dc )
  920. {
  921.     LOGPALETTE *LogicalPalette;
  922.     HPALETTE StockPalette;
  923.     UINT PaletteSize, StockPaletteSize, EntriesToCopy;
  924.  
  925.     if ( (Dc != NULL) && (NULL == tkhpalette) )
  926.     {
  927.                 PaletteSize = 256; //(Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);
  928.  
  929.                 LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
  930.                                         (PaletteSize * sizeof(PALETTEENTRY)) );
  931.  
  932.                 if ( NULL != LogicalPalette )
  933.                 {
  934.                     LogicalPalette->palVersion    = 0x300;
  935.                     LogicalPalette->palNumEntries = PaletteSize;
  936.  
  937.                     StockPalette     = GetStockObject(DEFAULT_PALETTE);
  938.                     StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
  939.  
  940.                     /*
  941.                      *  start by copying default palette into new one
  942.                      */
  943.  
  944.                     EntriesToCopy = StockPaletteSize < PaletteSize ?
  945.                                         StockPaletteSize : PaletteSize;
  946.  
  947.                     GetPaletteEntries( StockPalette, 0, EntriesToCopy,
  948.                                         LogicalPalette->palPalEntry );
  949.  
  950.                     /*
  951.                      *  If we are taking possession of the system colors,
  952.                      *  must guarantee that 0 and 255 are black and white
  953.                      *  (respectively).
  954.                      */
  955.  
  956.                     tkhpalette = CreatePalette(LogicalPalette);
  957.  
  958.                     FreeMemory(LogicalPalette);
  959.  
  960.                     RealizePaletteNow( Dc, tkhpalette);
  961.                 }
  962.             }
  963.     return( tkhpalette );
  964. }
  965. static void
  966. PrintMessage( const char *Format, ... )
  967. {
  968.     va_list ArgList;
  969.     char Buffer[256];
  970.  
  971.     va_start(ArgList, Format);
  972.     vsprintf(Buffer, Format, ArgList);
  973.     va_end(ArgList);
  974.  
  975.     MessageBox(GetFocus(), Buffer, "Error", MB_OK);
  976. }
  977.  
  978. static void
  979. DelayPaletteRealization( void )
  980. {
  981.     MSG Message;
  982.  
  983.     TKASSERT(NULL!=tkhwnd);
  984.  
  985.     /*
  986.      *  Add a WM_USER message to the queue, if there isn't one there already.
  987.      */
  988.  
  989.     if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
  990.     {
  991.         PostMessage( tkhwnd, WM_USER, 0, 0);
  992.     }
  993. }
  994.  
  995. /******************************Public*Routine******************************\
  996. * RealizePaletteNow
  997. *
  998. * Select the given palette in background or foreground mode (as specified
  999. * by the bForceBackground flag), and realize the palette.
  1000. *
  1001. * If static system color usage is set, the system colors are replaced.
  1002. *
  1003. * History:
  1004. *  26-Apr-1994 -by- Gilman Wong [gilmanw]
  1005. * Wrote it.
  1006. \**************************************************************************/
  1007.  
  1008. static long RealizePaletteNow( HDC Dc, HPALETTE Palette)
  1009. {
  1010.     long Result = -1;
  1011.     TKASSERT( NULL!=Dc      );
  1012.     TKASSERT( NULL!=Palette );
  1013.     if ( NULL != SelectPalette( Dc, Palette, FALSE ) )
  1014.     {
  1015.       Result = RealizePalette( Dc );
  1016.       WMesaPaletteChange(Palette);
  1017.     }
  1018.     return( Result );
  1019. }
  1020.  
  1021. static void
  1022. ForceRedraw( HWND Window )
  1023. {
  1024.     MSG Message;
  1025.  
  1026.     if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  1027.     {
  1028.         InvalidateRect( Window, NULL, FALSE );
  1029.     }
  1030. }
  1031. static void
  1032. DestroyThisWindow( HWND Window )
  1033. {
  1034.     if ( NULL != Window )
  1035.     {
  1036.         DestroyWindow( Window );
  1037.     }
  1038. }
  1039.  
  1040. /*
  1041.  *  This Should be called in response to a WM_DESTROY message
  1042.  */
  1043.  
  1044. static void
  1045. CleanUp( void )
  1046. {
  1047.     HPALETTE hStock;
  1048.  
  1049. // Cleanup the palette.
  1050.  
  1051.     if ( NULL != tkhpalette )
  1052.     {
  1053.     // If static system color usage is set, restore the system colors.
  1054.  
  1055.         if ((hStock = GetStockObject( DEFAULT_PALETTE ))!=NULL)
  1056.           SelectPalette( tkhdc, hStock, FALSE );
  1057.         DeleteObject( tkhpalette );
  1058.     }
  1059.  
  1060. // Cleanup the DC.
  1061.  
  1062.     if ( NULL != tkhdc )
  1063.         ReleaseDC( tkhwnd, tkhdc );
  1064. // Be really nice and reset global values.
  1065.     tkhwnd        = NULL;
  1066.     tkhdc         = NULL;
  1067.     tkhpalette    = NULL;
  1068.  
  1069.     ExposeFunc    = NULL;
  1070.     ReshapeFunc   = NULL;
  1071.     IdleFunc      = NULL;
  1072.     DisplayFunc   = NULL;
  1073.     KeyDownFunc   = NULL;
  1074.     MouseDownFunc = NULL;
  1075.     MouseUpFunc   = NULL;
  1076.     MouseMoveFunc = NULL;
  1077. }
  1078.  
  1079. static void *
  1080. AllocateMemory( size_t Size )
  1081. {
  1082.     return( LocalAlloc( LMEM_FIXED, Size ) );
  1083. }
  1084.  
  1085. static void *
  1086. AllocateZeroedMemory( size_t Size )
  1087. {
  1088.     return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
  1089. }
  1090.  
  1091.  
  1092. static void
  1093. FreeMemory( void *Chunk )
  1094. {
  1095.     TKASSERT( NULL!=Chunk );
  1096.  
  1097.     LocalFree( Chunk );
  1098. }
  1099.